package excelBase;

import java.util.ArrayList;

import main.ErrorException;
import script.Attribute;
import script.Variable;
import define.AttributeType;
import define.Common;
import define.Config;
import define.ErrorDefine;

public abstract class BaseContent 
{
	protected String m_name;
	protected ArrayList<BaseContent> m_children;
	
	public BaseContent(String name)
	{
		m_name = name;
	}
	
	public String getName()
	{
		return m_name;
	}
	
	public int getChildNumber()
	{
		if(m_children == null)
		{
			return 0;
		}
		return m_children.size();
	}

	public BaseContent getChild(int index, int position) throws ErrorException
	{
		if(m_children == null || index < 0 || index >= m_children.size())
		{
			throw new ErrorException(ErrorDefine.E_CHILD_OUT_OF_RANGE_ERROR, "" + index, position);
		}
		return m_children.get(index);
	}
	
	public BaseContent getChild(String name, int position) throws ErrorException
	{
		if(m_children == null)
		{
			throw new ErrorException(ErrorDefine.E_CANT_FIND_CHILD_ERROR, name, position);
		}
		for(BaseContent temp: m_children)
		{
			if(temp.getName().compareTo(name) == 0)
			{
				return temp;
			}
		}
		throw new ErrorException(ErrorDefine.E_CANT_FIND_CHILD_ERROR, name, position);
	}
	
	public BaseContent getChildIgnoreCase(String name, int position) throws ErrorException
	{
		if(m_children == null)
		{
			throw new ErrorException(ErrorDefine.E_CANT_FIND_CHILD_ERROR, name, position);
		}
		for(BaseContent temp: m_children)
		{
			if(temp.getName().toLowerCase().compareTo(name.toLowerCase()) == 0)
			{
				return temp;
			}
		}
		throw new ErrorException(ErrorDefine.E_CANT_FIND_CHILD_ERROR, name, position);
	}
	
	public int hasChild(String name)
	{
		if(m_children == null)
		{
			return Config.NO_FIND;
		}
		for(int i = 0, max = m_children.size(); i < max; ++i)
		{
			if(m_children.get(i).getName().compareTo(name) == 0)
			{
				return i;
			}
		}
		return Config.NO_FIND;
	}
	
	public String getAttributeValue(Attribute attr, String input) throws ErrorException
	{
		switch(attr.getType()) 
		{
		case E_LENGTH_ATTR:
			return getLength(input);
		case E_LAST_ATTR:
			return getLast();
		case E_LOW_FIRST_ATTR:
			return getLowFirst(input);
		case E_UP_FIRST_ATTR:
			return getUpFirst(input);
		case E_TO_LOW_ATTR:
			return getLower(input);
		case E_TO_UP_ATTR:
			return getUper(input);
		case E_SPLIT_ATTR:
			return getSplit(input, attr);
		case E_SIZE_ATTR:
			return getSize(attr.getPosition());
		case E_COUNT_ATTR:
			return getCount(attr.getVariable(), attr.getPosition());
		case E_GET_ATTR:
			return getGet(attr.getVariable(), attr.getIsString(), attr.getPosition());
		default:
			return "";
		}
	}
	
	private String getCount(Variable var, int position) throws ErrorException
	{
		if(m_children == null)
		{
			return "0";
		}
		if(var == null)
		{
			throw new ErrorException(ErrorDefine.E_ATTRIBUTE_WRONG_ERROR, position);
		}
		int count = 0;
		String value = var.getValue().toString();
		for(BaseContent base: m_children)
		{
			if(value.compareTo(base.getName()) == 0)
			{
				++count;
			}
		}
		return "" + count;
	}
	
	private String getSize(int position) throws ErrorException
	{
		if(m_children == null)
		{
			throw new ErrorException(ErrorDefine.E_CANT_USE_ATTR_ERROR, AttributeType.E_SIZE_ATTR.getKeyword(), position);
		}
		else
		{
			return m_children.size() + "";
		}
	}
	
	private String getLength(String input)
	{
		return input.length() + "";
	}
	
	private String getLast()
	{
		if(m_children == null)
		{
			return "0";
		}
		else
		{
			return (m_children.size() - 1) + "";
		}
	}
	
	private String getLowFirst(String input)
	{
		String first = input.substring(0, 1);
		first = first.toLowerCase();
		return first + input.substring(1);
	}
	
	private String getUpFirst(String input)
	{
		String first = input.substring(0, 1);
		first = first.toUpperCase();
		return first + input.substring(1);
	}
	
	private String getLower(String input)
	{
		return input.toLowerCase();
	}
	
	private String getUper(String input)
	{
		return input.toUpperCase();
	}
	
	private String getGet(Variable var, Boolean isString, int position) throws ErrorException
	{
		if(!(this instanceof Node))
		{
			throw new ErrorException(ErrorDefine.E_ATTRIBUTE_TYPE_MATCH_ERROR, AttributeType.E_GET_ATTR.getKeyword(), position);
		}
		String out = null;
		if(var == null)
		{
			out = ((Node)this).getValue();
		}
		else
		{
			if(isString)
			{
				out = ((Node)this).getAttribute(var.getValue().toString());
			}
			else
			{
				Integer i = Common.isInt(var.getValue().toString());
				if(i == null)
				{
					throw new ErrorException(ErrorDefine.E_VARIABLE_MUST_NUMBER_ERROR, var.getValue().toString(), position);
				}
				out = ((Node)this).getAttribute(i);
			}
		}
		if(out == null)
		{
			throw new ErrorException(ErrorDefine.E_CANT_FIND_CHILD_ERROR, position);
		}
		return out;
	}
	
	private String getSplit(String input, Attribute attr) throws ErrorException
	{
		int start = attr.getStart();
		int end = attr.getEnd();
		int len = input.length();
		if(start < 0)
		{
			start = len + start;
		}
		if(end < 0)
		{
			end = len + end;
		}
		if(start > end)
		{
			throw new ErrorException(ErrorDefine.E_SUBSTRING_ERROR, attr.getPosition());
		}
		if(start >= len)
		{
			return "";
		}
		if(end + 1 >= len)
		{
			return input.substring(start);
		}
		return input.substring(start, end + 1);
	}
}
